package com.zx.flow.api.util;

import com.zx.flow.api.config.FlowConfigNode;
import com.zx.flow.api.dict.FlowDict.Event;
import com.zx.flow.api.dict.FlowDict.NodeStatus;
import com.zx.flow.api.exception.FlowException;
import com.zx.flow.api.execute.model.FlowContext;
import com.zx.flow.api.execute.model.FlowNode;
import com.zx.flow.api.execute.model.FlowOperator;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

public class FlowDataUtil {

    public static FlowNode nodeCreate(FlowContext flow, FlowConfigNode configNode, List<FlowOperator> operators,
            String nodeFormId) {
        // 创建节点信息
        FlowNode node = new FlowNode();
        node.setId(UUID.randomUUID().toString());
        node.setFlowId(flow.getId());
        node.setStartDateTime(new Date());
        node.setEndDateTime(null);
        node.setEventCode("");
        node.setEventName("");
        // 上一个node
        List<FlowNode> nodes = flow.getNodes();
        if (CollectionUtils.isEmpty(nodes)) {
            flow.setNodes(new ArrayList<>());
            node.setNodeFormId("");
            node.setNodeFormCode("");
            node.setNodeFormName("");
            node.setNodeIdx(0);
        } else if (!StringUtils.isEmpty(nodeFormId)) {
            FlowNode formNode = getNodeById(nodes, nodeFormId);
            node.setNodeFormId(formNode.getId());
            node.setNodeFormCode(formNode.getNodeCurrentCode());
            node.setNodeFormName(formNode.getNodeCurrentName());
            node.setNodeIdx(nodes.size());
        } else {
            FlowNode lastNode = getCurrent(flow);
            node.setNodeFormId(lastNode.getId());
            node.setNodeFormCode(lastNode.getNodeCurrentCode());
            node.setNodeFormName(lastNode.getNodeCurrentName());
            node.setNodeIdx(nodes.size());
        }
        node.setNodeCurrentCode(configNode.getCode());
        node.setNodeCurrentName(configNode.getName());
        //下一个
        node.setNodeToId("");
        node.setNodeToCode("");
        node.setNodeToName("");
        node.setOperator(null);
        node.setRemark("");
        node.setSubFlowId("");
        node.setStatus(NodeStatus.doing);

        // 获得审批人
        if (CollectionUtils.isEmpty(operators)) {
            node.setOperators(OperatorsUtil.getOperator(flow, node, Event.nodeEntry, configNode.getOperators()));
        } else {
            node.setOperators(operators);
        }
        return node;
    }

    /**
     * 获得当前节点【即 最新的节点】
     *
     * @param flow
     * @return
     */
    public static FlowNode getCurrent(FlowContext flow) {
        if (flow == null) {
            return null;
        }
        List<FlowNode> nodes = flow.getNodes();
        if (CollectionUtils.isEmpty(nodes)) {
            return null;
        }
        // 获得最新一个node
        FlowNode currNode = getNodeByIdx(nodes, nodes.size() - 1);
        if (currNode != null && Objects.equals(currNode.getNodeCurrentCode(), flow.getCurrentNodeCode())) {
            return currNode;
        }
        throw new FlowException("获得当前节点失败, 数据异常, flowCode=" + flow.getCurrentNodeCode()
                + ", nodeCode=" + currNode.getNodeCurrentCode());
    }

    /**
     * 获得某个node
     *
     * @param nodes
     * @param idx
     * @return
     */
    public static FlowNode getNodeByIdx(List<FlowNode> nodes, int idx) {
        //return nodes.stream().filter(n -> n.getNodeIdx().intValue() == idx).findAny().orElseGet(() -> null);
        return nodes.get(idx);
    }

    public static FlowNode getNodeById(List<FlowNode> nodes, String id) {
        return nodes.stream().filter(n -> Objects.equals(id, n.getId())).findAny().orElseGet(() -> null);
    }

    /**
     * 更新node
     *
     * @param node
     * @param event
     * @param toNodeConfig
     * @param remark
     * @param accountCode
     * @return
     */
    public static void nodeFinish(FlowNode node, Event event, FlowConfigNode toNodeConfig, String remark,
            String accountCode) {
        node.setEndDateTime(new Date());
        // 获得操作人
        FlowOperator operator = OperatorsUtil.find(node.getOperators(), accountCode);
        // 没有操作人的时候，如果发现是system操作，就可以忽略操作人列表，直接操作
        if (operator == null && OperatorsUtil.checkSystem(accountCode)) {
            operator = OperatorsUtil.getSystem();
        }
        node.setOperator(operator);
        // 触发的事件
        node.setEventCode(event.getCode());
        node.setEventName(node.getOperator().getAccountName() + "[" + event.getName() + "]");
        // 下一个节点
        if (toNodeConfig != null) {
            node.setNodeToCode(toNodeConfig.getCode());
            node.setNodeToName(toNodeConfig.getName());
        }
        node.setRemark(remark);
        node.setStatus(NodeStatus.finish);
    }
}
